﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using SPCFMedicineInformer.Helpers;
using System.Data;
using SPCFMedicineInformer.DocumentTypes;
using Vega.USiteBuilder;
using System.Text;
using umbraco.cms.businesslogic.web;
using umbraco.BusinessLogic;
using SPCFMedicineInformer.Members;
using SPCFMedicineInformer.Constants;
using umbraco.NodeFactory;
using umbraco;

namespace SPCFMedicineInformer.Masterpages
{
    public partial class Consultation : System.Web.UI.MasterPage
    {
        #region declaration
        public List<MedicineCategory> CategoryList { get; set; }
        public List<Medicines> MedicineList { get; set; }
        int id;
        string userName = string.Empty;
        List<string> condsId = new List<string>();
        List<string> sympsList = new List<string>();
        List<string> condsName = new List<string>();
        List<string> sympsName = new List<string>();
        public string allergicMedicines = "";
        
        #endregion
        public class Medicines
        {
            public int Id { get; set;}
            public string MedicineName { get; set; }
        }
        protected void Page_Load(object sender, EventArgs e)
        {
            CategoryList = NodeLocator.GetNodesOfExactType<MedicineCategory>().Where(node=> !node.HideInConsultation).ToList();
            var User = HttpContext.Current.User.Identity;
            if (!string.IsNullOrEmpty(User.Name))
            {
                var member = MemberHelper.GetMemberFromLoginName(User.Name) as WebUser;
                member = member != null ? member : MemberHelper.GetMemberFromEmail(User.Name) as WebUser;
                if (member != null)
                {
                    id = member.Id;
                    userName = member.Email;
                    
                }
                if (!IsPostBack)
                {
                    ShowPlaceHolder(plcStep1);
                    MedicineList = null;
                    if (member != null)
                        GetLatestConsultationPersonalInfo(member);
                    LoadDates();
                }
            }
        }
        void GetLatestConsultationPersonalInfo(WebUser user)
        {
            
            if (user != null)
            {
                txtAddress.Text = user.Address;
                rdoGender.Text = user.Gender;
                DateTime bDate;
                if (DateTime.TryParse(user.Birthdate, out bDate))
                {
                    ddlMonth.SelectedValue = bDate.Month.ToString();
                    ddlDay.SelectedValue = bDate.Day.ToString();
                    ddlYear.SelectedValue = bDate.Year.ToString();
                }
                
            }
        }
        protected void btnStepSubmit_Click(object sender, EventArgs e)
        {
            Button btn = (Button)sender;
            if (btn.ID == "btnStep1Submit" && IsValidatePlc1())
            {
                ShowPlaceHolder(plcStep2);
                var list = NodeLocator.GetNodesOfExactType<MedicineItem>().OrderBy(a => a.Name).Select(a => new Medicines
                {
                    Id = a.Id,
                    MedicineName = a.Name,
                    
                }).ToList();
                MedicineList = list;
            }   
            else if (btn.ID == "btnStep2Submit" && IsValidatePlc2())
            {
                
                DisplayCondtions(hiddenChosenSymptoms.Value);
                SaveConsultation();
                ShowPlaceHolder(plcStep3);
                if (rdoHasAllergies.Text.ToLower() == "yes")
                {
                    allergicMedicines = FormHelper.ParseNameToId(txtAllergies.Text);
                }
            }
            else if (btn.ID == "btnStep2Back")
                ShowPlaceHolder(plcStep1);
                
        }
        bool IsValidatePlc1()
        {
            bool value = true;
            var sb = new StringBuilder();
            var msgFormat = "<p class=\"{0}\">{1}</p>";
            
            
            
            if (rdoGender.Text == "")
            {
                sb.AppendLine(string.Format(msgFormat, "msg warning", "Please select you gender."));
                value = false;
            }
            string birthdate = string.Concat(ddlMonth.Items[ddlMonth.SelectedIndex].Text, " ", ddlDay.Items[ddlDay.SelectedIndex].Text, " ,", ddlYear.Items[ddlYear.SelectedIndex].Text);
            if (ddlDay.SelectedValue == "0" || ddlMonth.SelectedValue == "0" || ddlYear.SelectedValue == "0")
            {
                sb.AppendLine(string.Format(msgFormat, "msg warning", "Please enter your birthdate."));
                value = false;
            }
            else if (FormHelper.GetAge(birthdate) < 0)
            {

                sb.AppendLine(string.Format(msgFormat, "msg warning", "Birthdate is not valid. Please double check."));
                value = false;
            }

            if (!value)
            {
                MsgLiteral.Visible = true;
                MsgLiteral.Text = sb.ToString();
                
            }
            return value;
        }
        bool IsValidatePlc2()
        {
            bool value = true;
            var sb = new StringBuilder();
            var msgFormat = "<p class=\"{0}\">{1}</p>";

            if (string.IsNullOrEmpty(hiddenChosenSymptoms.Value.Replace(",","")))
            {
                sb.AppendLine(string.Format(msgFormat, "msg warning", "Please select atleast one symptom."));
                value = false;
            }
            if (!value)
            {
                MsgLiteral.Visible = true;
                MsgLiteral.Text = sb.ToString();

            }
            return value;
        }
        void SaveConsultation()
        {
            var cf = UmbracoNodeHelper.GetWebsitePage(Constants.SearchType.NodeTypeAlias, "ConsulationFolder");
            DocumentType UmbracoDocType = DocumentType.GetByAlias("Consultation");
            
            if (cf != null && cf.Id > 0)
            {
                string nodeName = id.ToString() + "-" + DateTime.Now;
                Document d = Document.MakeNew(nodeName, UmbracoDocType, User.GetUser(0), cf.Id);
                TransferDetailsToUmbraco(d);
            }
        }
        void TransferDetailsToUmbraco(Document d)
        {
            string birthdate = string.Concat(ddlMonth.Items[ddlMonth.SelectedIndex].Text, " ", ddlDay.Items[ddlDay.SelectedIndex].Text, " ,", ddlYear.Items[ddlYear.SelectedIndex].Text);
            txtAge.Text = FormHelper.GetAge(birthdate).ToString();
            d.getProperty(UmbracoPropertyName.CONSULTATION_USER_ID).Value = id;
            d.getProperty(UmbracoPropertyName.CONSULTATION_USER_NAME).Value = userName;
            d.getProperty(UmbracoPropertyName.CONSULTATION_DATE_OF_CONSULTATION).Value = DateTime.Now;
            d.getProperty(UmbracoPropertyName.CONSULTATION_CONSULTANT_NAME).Value = ddlName.Text;
            d.getProperty(UmbracoPropertyName.CONSULTATION_GENDER).Value = rdoGender.Text;
            d.getProperty(UmbracoPropertyName.CONSULTATION_ADDRESS).Value = txtAddress.Text;
            d.getProperty(UmbracoPropertyName.CONSULTATION_DATE_OF_BIRTH).Value = birthdate;
            d.getProperty(UmbracoPropertyName.CONSULTATION_HAS_ALLERGY_WITH_MEDICINE).Value = rdoHasAllergies.SelectedItem.Text;
            d.getProperty(UmbracoPropertyName.CONSULTATION_AGE).Value = txtAge.Text;
            d.getProperty(UmbracoPropertyName.CONSULTATION_SYMPTOMS).Value = string.Join(",", sympsList);
            d.getProperty(UmbracoPropertyName.CONSULTATION_POSSIBLE_MEDICINES).Value = string.Join(",", condsId);
            d.getProperty(UmbracoPropertyName.CONSULTATION_SYMPTOMS_NAME).Value = string.Join(",", sympsName);
            d.getProperty(UmbracoPropertyName.CONSULTATION_POSSIBLE_MEDICINES_NAME).Value = string.Join(",", condsName);
            if (rdoHasAllergies.Text.ToLower() == "yes")
            {
                d.getProperty(UmbracoPropertyName.CONSULTATION_ALLERGY_NAME).Value = FormHelper.ParseNameToId(txtAllergies.Text);
            }
            else if (rdoHasAllergies.SelectedItem.Text.ToLower() == "other")
            {
                d.getProperty(UmbracoPropertyName.CONSULTATION_ALLERGY_NAME).Value = "Please check your Doctor/Health provider before taking the medicine(s).";
            }
            d.Publish(User.GetUser(0));
            umbraco.library.UpdateDocumentCache(d.Id);

        }
        void DisplayCondtions(string symps)
        {
            string hasAllergy = rdoHasAllergies.Text;
            //create a list from the symptoms chosen
            sympsList = symps.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries).ToList();
            litChosenSymptomCount.Text = sympsList.Count().ToString();
            List<string> condsIdList = new List<string>();
            foreach (var symp in sympsList)
            {
                var condTempList = NodeLocator.GetNodesOfExactType<Condition>().Where(a => a.SymptomTag.ToString().Contains(symp)).ToList();
                int tempInt;
                int id = int.TryParse(symp, out tempInt) ? tempInt : 0;
                var node = new Node(id);
                if (node != null)
                    sympsName.Add(node.Name);
                
                
                if (condTempList.Count > 0)
                    condsIdList.AddRange(condTempList.Select(a => a.Id.ToString()).ToList());

            }
            //group list by occurrence
            var conditionGroup = (from c in condsIdList
                                  group c by c into g
                                  select new
                                  {
                                      c = g.Key,
                                      count = g.Count(),
                                  }).OrderByDescending(c => c.count);
            List<Condition> conds = new List<Condition>();
            foreach (var item in  conditionGroup)
            {
                int tempInt;
                int id = int.TryParse(item.c,out tempInt) ? tempInt : 0;
                if (id > 0)
                {
                    var condItem = ContentHelper.GetByNodeId<Condition>(id);
                    conds.Add(condItem);
                    condsId.Add(condItem.Id.ToString());
                    condsName.Add(condItem.Name);
                }
                
            }
            var newConds = conds.Select(node => new ConditionOutput(node.SymptomTag, hiddenChosenSymptoms.Value)
                            {
                                Id = node.Id,
                                ConditionNames = node.Name,
                                ImageUrl = node.ImageUrl,
                                Description = node.Description
                            }).ToList().OrderByDescending(a => a.Average).ToList();
            
            rptSuggestedMedicines.DataSource = newConds;
            rptSuggestedMedicines.DataBind();

        }
        public class ConditionOutput
        {
            string _symptomTag;
            string _chosenSymptoms;
            public string ImageUrl { get; set; }
            public string Description { get; set; }
            List<string> chosenList
            {
                get
                {
                    return _chosenSymptoms.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries).ToList();
                }
            }
            List<string> conditionList
            {
                get
                {
                    return uQuery.GetNodesByCsv(_symptomTag).Select(node => node.Id.ToString()).ToList();
                }
            }
            int chosenWithoutOnConditionCount
            {
                get 
                {
                    return chosenList.Except(conditionList).ToList().Count();
                }
            }
            public int MatchCount
            {
                get 
                {
                    return ChosenCount - chosenWithoutOnConditionCount;
                }
            }
            public ConditionOutput(string symptomTag,string chosenSymptoms)
            {
                _symptomTag = symptomTag;
                _chosenSymptoms = chosenSymptoms;
            }
            public int Id { get; set; }
            public string ConditionNames { get; set; }
            public int ChosenCount
            {
                get
                {
                    return chosenList.Count();
                }
            }
            public int ConditionCount 
            {
                get
                {
                    return conditionList.Count();
                }
            }
            double chosenPercent
            {
                get
                {
                    return Math.Round(Convert.ToDouble((Convert.ToDouble(MatchCount) / Convert.ToDouble(ChosenCount)) * 100), 2);
                }
            }
            double conditionPercent
            {
                get 
                {
                   return  Math.Round(Convert.ToDouble((Convert.ToDouble(MatchCount) / Convert.ToDouble(ConditionCount)) * 100), 2);
                }
            }
            public double Average
            {
                get
                {
                    return Math.Round(((chosenPercent + conditionPercent) / 2), 2);
                }
            }
        }
        void ShowPlaceHolder(PlaceHolder plc)
        {
            plcStep1.Visible = false;
            plcStep2.Visible = false;
            plcStep3.Visible = false;
            plc.Visible = true;
            MsgLiteral.Visible = false;
        }
        protected void Repeater_ItemDatabound(object sender, RepeaterItemEventArgs e)
        {
            if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
            {
                Condition  c = (Condition)e.Item.DataItem;
                if (!string.IsNullOrEmpty(c.Name))
                {
                    try
                    {
                        Literal lit = (Literal)e.Item.FindControl("litPercentage");
                        Literal litNoOfSymptoms = (Literal)e.Item.FindControl("litNoOfSymptoms");
                        Literal litMatchOverCondtionSymptoms = (Literal)e.Item.FindControl("litMatchOverCondtionSymptoms");
                        Literal litMatchOverChosenSymptoms = (Literal)e.Item.FindControl("litMatchOverChosenSymptoms");

                        List<string> conditionList = uQuery.GetNodesByCsv(c.SymptomTag).Select(node=>node.Id.ToString()).ToList();
                        var chosenList = hiddenChosenSymptoms.Value.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                        int chosenCount = chosenList.Count();
                        int conditionCount = conditionList.Count;
                        int chosenWithoutOnConditionCount = chosenList.Except(conditionList).ToList().Count();
                        int matchCount = chosenCount - chosenWithoutOnConditionCount;
                        

                        double chosenPercent = Math.Round(Convert.ToDouble((Convert.ToDouble(matchCount) / Convert.ToDouble(chosenCount)) * 100), 2);
                        double conditionPercent = Math.Round(Convert.ToDouble((Convert.ToDouble(matchCount) / Convert.ToDouble(conditionCount)) * 100), 2);
                        
                        double average = Math.Round(((chosenPercent + conditionPercent) / 2), 2);
                        lit.Text = average.ToString() + "%";
                        litNoOfSymptoms.Text = conditionCount.ToString();
                        litMatchOverCondtionSymptoms.Text = string.Concat(matchCount.ToString(), " out of ", conditionCount.ToString());
                        litMatchOverChosenSymptoms.Text = string.Concat(matchCount.ToString(), " out of ", chosenCount.ToString());
                    }
                    catch (Exception ex)
                    {
                    }
                    
                }
            }

        }
        void LoadDates()
        {
            DateTime dteDefault = DateTime.Parse("1/1/2012");
            DataTable dtMonth = new DataTable();
            DataTable dtDay = new DataTable();
            DataTable dtYear = new DataTable();
            DataRow dr = null;

            dtMonth.Columns.Add(new DataColumn("TextField"));
            dtMonth.Columns.Add(new DataColumn("ValueField"));
            dtDay = dtMonth.Copy();
            dtYear = dtMonth.Copy();

            string textField = "TextField";
            string valueField = "ValueField";

            dr = dtMonth.NewRow();
            dr[textField] = "Month";
            dr[valueField] = "0";
            dtMonth.Rows.Add(dr);
            for (int mon = 1; mon <= 12; mon++)
            {
                dr = dtMonth.NewRow();
                dr[textField] = dteDefault.ToString("MMMM");
                dr[valueField] = mon;
                dtMonth.Rows.Add(dr);
                dteDefault = dteDefault.AddMonths(1);
            }


            dr = dtDay.NewRow();
            dr[textField] = "Day";
            dr[valueField] = "0";
            dtDay.Rows.Add(dr);
            for (int day = 1; day <= 31; day++)
            {
                dr = dtDay.NewRow();
                dr[textField] = day;
                dr[valueField] = day;
                dtDay.Rows.Add(dr);
            }

            dr = dtYear.NewRow();
            dr[textField] = "Year";
            dr[valueField] = "0";
            dtYear.Rows.Add(dr);
            for (int year = DateTime.Now.Year; year >= DateTime.Now.AddYears(-85).Year; year--)
            {
                dr = dtYear.NewRow();
                dr[textField] = year;
                dr[valueField] = year;
                dtYear.Rows.Add(dr);
            }

            FormHelper.BindDropDown(ddlDay, dtDay, textField, valueField);
            FormHelper.BindDropDown(ddlMonth, dtMonth, textField, valueField);
            FormHelper.BindDropDown(ddlYear, dtYear, textField, valueField);
        }
    }
}